package com.ruoyi.backend.service.Impl;

import com.ruoyi.backend.dto.UavInfoUpdateDTO;
import com.ruoyi.backend.util.*;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.backendEnum.FileUtilsException;
import com.ruoyi.common.exception.backendEnum.UavException;
import com.ruoyi.backend.dto.UavUploadDTO;
import com.ruoyi.backend.mapper.UavMapper;
import com.ruoyi.backend.pojo.Uav;
import com.ruoyi.backend.service.UavsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDate;
import java.util.List;

@Slf4j
@Service
public class UavsServiceImpl implements UavsService {

    @Resource(name = "redisTemplate")
    private ValueOperations<String, String> valueOperations;

    @Resource(name = "redisTemplate")
    private HashOperations<String, String, Boolean> hashOperations;


    @Autowired
    private UavMapper uavMapper;


    @Autowired
    private MinioUtil minioUtil;

    @Value("${minio-bucket.uavfile}")
    private String minioBucketName;

    @Override
    public void upload(UavUploadDTO uavUploadDTO) throws IOException {

        if (uavUploadDTO.getMd5() != null){
//            String md5 = uavUploadDTO.getMd5(); // 获取前端传来的 MD5
//            String redisKey = Constants.FILE_MD5_KEY + md5;
//            String existingFilePath = valueOperations.get(redisKey);
//
//            String newName = CommmonFileUtils.generateUUIDName(existingFilePath);
//            String currenttFilePath = "/uav/" + newName;
//            // CommmonFileUtils.fileReName(, newName);
//
//            if (CommmonFileUtils.obtainFileExtension(newName).equals(".zip"))
//            {
//                try {
//                    // 解压文件
//                    ZipUtil.unzip(existingFilePath, existingFilePath.substring(0, existingFilePath.lastIndexOf(".")));
//                } catch (IOException e) {
//                    throw new ServiceException(UavException.FILE_UNZIP_FAIL);
//                }
//            }
//
//            uavUploadDTO.setImagePath(currenttFilePath);
//            uavUploadDTO.setUavId(generateEcologicalId(uavUploadDTO.getMineId(), uavUploadDTO.getDataType()));

            // 超大文件如何发布需要另外考虑
            uavMapper.upload(uavUploadDTO);
        }else {

            MultipartFile file = uavUploadDTO.getFile();

            //获取原始文件名
            String originalFileName = uavUploadDTO.getUavName();
            //生成minio文件名：系统时分秒+原始文件名
            String minioFileName=CommmonFileUtils.getMinioFileName(originalFileName);
            uavUploadDTO.setMinioBucketName(minioBucketName);
            uavUploadDTO.setMinioFileName(minioFileName);
            uavUploadDTO.setUavId(generateEcologicalId(uavUploadDTO.getMineId(), uavUploadDTO.getDataType()));
            //上传minio
            minioUtil.uploadFile(minioBucketName, minioFileName, file);


            // 获取文件后缀名
            String extension = CommmonFileUtils.getExtension(originalFileName);

            if (extension == null){
                throw new ServiceException(FileUtilsException.FILE_EXTENSION_NOT_EXIST);
            } else if (extension.equals(".zip")) {
                //TODO:zip文件处理

               // ZipUtil.unzip(targetFile.getAbsolutePath(), targetFile.getAbsolutePath().replace(".zip", ""));
                uavMapper.upload(uavUploadDTO);
            } else if (extension.equals(".tif") || extension.equals(".tiff")) {
                // TODO:TIF 文件处理：直接传桶名 + 文件名给 Python
                // String result = pythonApiClient.sendSatelliteImageRelease(minioBucketName, minioFileName);
                // log.info("Geoserver影像发布结果: " + result + ", 时间: " + LocalDate.now());

                // 上传数据库表
                uavMapper.upload(uavUploadDTO);


            } else
                uavMapper.upload(uavUploadDTO);
        }
    }

    @Override
    public List<Uav> search(String mineId, String uavName, LocalDate startTime, LocalDate endTime, String dataType, String saveType) {
        List<Uav> uavList = uavMapper.search(mineId, uavName, startTime, endTime, dataType, saveType);
//        if (uavList.isEmpty())
//            throw new ServiceException(UavException.UAV_DATA_NOT_FOUND);
        return uavList;
    }

    @Override
    public void delete(String uavId, LocalDate uavTime) {
        if (uavMapper.getCountUavId(uavId) == 0)
            throw new ServiceException(UavException.UAV_DATA_NOT_EXIST);
        //先查询要删除的无人机影像数据
        Uav uav = uavMapper.findById(uavId, uavTime);
        if (uav != null) {
            //删除minio文件
            String minioFileName=uav.getMinioFileName();
            boolean removed = minioUtil.removeFile(minioBucketName, minioFileName);
            if (!removed) {
                throw new ServiceException("删除 Minio 文件失败: " + minioFileName);
            }
        }
        //删除数据库表记录
        uavMapper.delete(uavId, uavTime);

    }

    @Override
    public void update(UavInfoUpdateDTO uav) {
        if (uavMapper.getCountUavId(uav.getUavId()) == 0)
            throw new ServiceException(UavException.UAV_DATA_NOT_EXIST);
        uavMapper.update(uav);
    }


    @Override
    public String generateEcologicalId(String mineId, String dataType) {


        // 拼接前缀 prefix，由 mine_id、dataCategoryCode 和 dataSourceCode 组成。
        String prefix = mineId + dataType;
        List<Uav> lastRecord = uavMapper.findByUavIdPrefix(prefix);
        String newIdSuffix = "00001";
        if (!lastRecord.isEmpty()) {
            String lastId = lastRecord.get(0).getUavId();
            String lastIdSuffix = lastId.substring(lastId.length() - 5);
            newIdSuffix = String.format("%05d", Integer.parseInt(lastIdSuffix) + 1);
        }
        System.out.println(prefix + newIdSuffix);
        return prefix + newIdSuffix;
    }
}
